package com.boot2.core.web;

import lombok.extern.apachecommons.CommonsLog;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HttpContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;

import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

/**
 * @author zhangweilin
 * @Description: xxxxx
 * @date 2020/5/26
 */
@CommonsLog
public abstract class AbstractRestTemplateConfig {

    @Autowired(required = false)
    OkHttpRetryIntercepter okHttpRetryIntercepter;

    /**
     * 创建okhttp工厂
      * @param maxIdleConnections
     * @param keepAliveDuration
     * @param connectTimeout
     * @param readTimeout
     * @return
     */
    protected OkHttp3ClientHttpRequestFactory okHttp3ClientHttpRequestFactory(int maxIdleConnections, long keepAliveDuration,int connectTimeout,int readTimeout) {
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectionPool(new ConnectionPool(maxIdleConnections, keepAliveDuration, TimeUnit.MINUTES))
                .retryOnConnectionFailure(true)
                .addInterceptor(okHttpRetryIntercepter)
                .build();


        //okhttp的实现
        OkHttp3ClientHttpRequestFactory okHttp3ClientHttpRequestFactory = new OkHttp3ClientHttpRequestFactory(okHttpClient);
        okHttp3ClientHttpRequestFactory.setConnectTimeout(connectTimeout);
        okHttp3ClientHttpRequestFactory.setReadTimeout(readTimeout);

        return okHttp3ClientHttpRequestFactory;
    }

    /**
     * 创建httpClient工厂
     * @param maxTotal
     * @param DefaultMaxPerRoute
     * @param validateAfterInactivity
     * @param connectTimeout
     * @param connectionRequestTimeout
     * @param timeout
     * @param retryCount
     * @return
     */
    protected HttpComponentsClientHttpRequestFactory httpClientRequestFactory(int maxTotal,int DefaultMaxPerRoute,int validateAfterInactivity,int connectTimeout,int connectionRequestTimeout,int timeout, int retryCount) {
        HttpClientBuilder clientBuilder = HttpClients.custom();

        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();

        // 整个连接池最大连接数
        connectionManager.setMaxTotal(maxTotal);
        // 设置每个路由的最大并发连接数,默认为2.
        connectionManager.setDefaultMaxPerRoute(DefaultMaxPerRoute);
        // 官方推荐使用检查永久链接的可用性,而不推荐每次请求的时候才去检查 (milliseconds 毫秒)
        connectionManager.setValidateAfterInactivity(validateAfterInactivity);

        clientBuilder.setConnectionManager(connectionManager);
        //设置重连操作次数，这里设置了3次
        clientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(retryCount, true, new ArrayList<>()) {

            @Override
            public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
                log.info("Retry request, execution count: " + executionCount + ", exception: " + exception);
                return super.retryRequest(exception, executionCount, context);
            }
        });

        //使用httpClient创建一个ClientHttpRequestFactory的实现
        HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(clientBuilder.build());
        httpRequestFactory.setConnectTimeout(connectTimeout);
        httpRequestFactory.setConnectionRequestTimeout(connectionRequestTimeout);
        httpRequestFactory.setReadTimeout(timeout);
        return httpRequestFactory;
    }
}
